﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Data;
using Dapper;
using BCEntity.Common.Wallet;
using BCCommon.Enums;
using BCCommon.PaymentEnums;
using BCCommon;

namespace BCData.Common.Wallet
{
    public class WalletTransferData : IWalletTransferData
    {
        #region 私有变量

        private readonly IDatabaseContext databaseContext;

        private readonly string _query = @"
SELECT
	{0}
FROM
	wallettransfer A
	INNER JOIN USER B ON A.UserId=B.UserId
";

        private readonly string _property = @"
	A.WalletTransferId,
	A.PaymentChannelId,
	A.AppType,
	A.OSType,
	A.UserId,
	A.Amount,
	A.STATUS,
	A.TransferMode,
	A.CreateTime,
	A.TransferTime,
	A.BankCardNo,
	A.OpenID,
	A.RejectRefuse,
	A.Remark,
	A.BankCardTransferNo,
	B.UserName,
	B.Phone
";

        #endregion 私有变量

        #region 构造函数

        public WalletTransferData(IDatabaseContext databaseContext)
        {
            this.databaseContext=databaseContext;
        }

        #endregion 构造函数

        #region 创建提现申请

        public WalletTransferExtendEntity Create(WalletTransferEntity entity)
        {
            var sql = SqlCommands.GetInsertSql("wallettransfer", new[] { "PaymentChannelId", "AppType", "OSType", "UserId", "Amount","Status",
                "TransferMode", "BankCardNo","RejectRefuse", "BankCardTransferNo" ,"Remark"});
            sql = $"{sql}{string.Format(_query, _property)} WHERE  A.WalletTransferId=LAST_INSERT_ID()";
            DynamicParameters parameters = new DynamicParameters();

            parameters.Add("?UserId", entity.UserId, DbType.Int64);
            parameters.Add("?Amount", entity.Amount, DbType.Decimal);
            parameters.Add("?PaymentChannelId", entity.PaymentChannelId, DbType.AnsiString, size: 20);
            parameters.Add("?Status", entity.Status, DbType.AnsiString, size: 20);
            parameters.Add("?OpenID", entity.OpenID, DbType.AnsiString, size: 50);
            parameters.Add("?AppType", entity.AppType, DbType.AnsiString, size: 20);
            parameters.Add("?OSType", entity.OSType, DbType.AnsiString, size: 20);
            parameters.Add("?TransferMode", entity.TransferMode);
            parameters.Add("?BankCardNo", entity.BankCardNo);
            parameters.Add("?RejectRefuse", entity.RejectRefuse);
            parameters.Add("?Remark", entity.Remark);
            parameters.Add("?BankCardTransferNo", entity.BankCardTransferNo);

            return this.databaseContext.Master.QueryEntity<WalletTransferExtendEntity>(sql, parameters, databaseContext.Transaction);
        }

        #endregion 创建提现申请

        public (List<WalletTransferExtendEntity>, int dataCount) GetUserWalletTransfer(long userId, int index, int size)
        {
            var sql = $"{string.Format(_query, _property)} WHERE A.UserId=?UserId LIMIT ?index,?size; {string.Format(_query, "COUNT(1)")} WHERE A.UserId=?UserId;";
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?UserId", userId);
            parameters.Add("?index", index);
            parameters.Add("?size", size);
            var data = this.databaseContext.Slave.QueryMultiple<WalletTransferExtendEntity, int>(sql, parameters);
            return (data.Item1.ToList(), data.Item2);
        }

        public WalletTransferExtendEntity Get(long walletTransferId)
        {
            string sql = $"{string.Format(_query, _property)} WHERE A.WalletTransferId=?WalletTransferId";
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?WalletTransferId", walletTransferId, DbType.Int64);
            return this.databaseContext.Slave.QueryEntity<WalletTransferExtendEntity>(sql, parameters);
        }

        public IEnumerable<WalletTransferExtendEntity> Get(int pageIndex, int pageSize, out int dataCount,
            CashOutStatusType? status, SourceAppType? appType, string userName, bool? @ascending = null, string phone = null)
        {
            List<string> wheres = new List<string>();
            DynamicParameters parameters = new DynamicParameters();
            if (status.HasValue)
            {
                wheres.Add("A.Status=?Status");
                parameters.Add("?Status", status.Value.ToString(), DbType.AnsiString);
            }
            if (appType.HasValue)
            {
                wheres.Add("A.AppType=?AppType");
                parameters.Add("?AppType", appType.Value.ToString(), DbType.AnsiString);
            }
            if (!string.IsNullOrWhiteSpace(userName))
            {
                wheres.Add(" B.UserName LIKE CONCAT('%',CONCAT(?UserName,'%'))");
                parameters.Add("?UserName", userName, DbType.AnsiString);
            }
            if (!string.IsNullOrWhiteSpace(phone))
            {
                wheres.Add("B.Phone=?Phone");
                parameters.Add("?Phone", phone, DbType.AnsiString);
            }
            string sql = string.Format("{0} {1} ORDER BY A.CreateTime {4} LIMIT {2}, {3}; {5} {1}",
                string.Format(_query, _property),
                wheres.Count > 0 ? "WHERE " + string.Join(" AND ", wheres) : string.Empty,
                (pageIndex == 0 ? 0 : pageIndex - 1) * pageSize,
                pageSize,
                ascending.HasValue && ascending.Value ? "ASC" : "DESC",
                string.Format(_query, "COUNT(1)"));

            var results = this.databaseContext.Slave.QueryMultiple<WalletTransferExtendEntity, int>(sql, parameters);
            dataCount = results.Item2;
            return results.Item1;
        }

        public WalletTransferEntity SetAsProcessing(long walletTransferId)
        {
            string sql = "UPDATE WalletTransfer SET Status = 'Processing' WHERE WalletTransferId=?WalletTransferId;SELECT WalletTransferId,UserId,Amount,paymentChannelId,Status,CreateTime,TransferTime,OpenID,RejectRefuse FROM WalletTransfer WHERE WalletTransferId=?WalletTransferId";
            DynamicParameters parameters = new DynamicParameters();

            parameters.Add("?WalletTransferId", walletTransferId, DbType.Int32);

            return this.databaseContext.Master.QueryEntity<WalletTransferEntity>(sql, parameters, databaseContext.Transaction);
        }

        public WalletTransferExtendEntity Approve(long walletTransferId, CashOutStatusType walletStatus,
            DateTime? transferTime)
        {
            string sql = "UPDATE WalletTransfer SET Status=?Status,TransferTime=?TransferTime WHERE WalletTransferId=?WalletTransferId;";

            sql = $"{sql} {string.Format(_query, _property)}  WHERE A.WalletTransferId=?WalletTransferId";

            DynamicParameters parameters = new DynamicParameters();

            parameters.Add("?Status", walletStatus.ToString(), DbType.AnsiString);
            parameters.Add("?TransferTime", transferTime, DbType.DateTime);
            parameters.Add("?WalletTransferId", walletTransferId, DbType.Int64);
            return this.databaseContext.Master.QueryEntity<WalletTransferExtendEntity>(sql, parameters, databaseContext.Transaction);
        }

        public WalletTransferExtendEntity Reject(long walletTransferId, string rejectRefuse)
        {
            string sql = @"UPDATE WalletTransfer SET Status = 'Failed',RejectRefuse=?RejectRefuse WHERE WalletTransferId = ?WalletTransferId;";

            sql = $"{sql} {string.Format(_query, _property)} WHERE WalletTransferId=?WalletTransferId";

            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?WalletTransferId", walletTransferId, DbType.Int32);
            parameters.Add("?RejectRefuse", rejectRefuse, DbType.String);
            return this.databaseContext.Master.QueryEntity<WalletTransferExtendEntity>(sql, parameters, databaseContext.Transaction);
        }

        /// <summary>
        /// 查询用户是否有待处理的提现记录
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <returns></returns>
        public bool CheckPendingWithdraw(long userId)
        {
            string sql = @"SELECT 1 FROM WalletTransfer WHERE UserId=?UserId AND Status =?Pending ";
            DynamicParameters parameters = new DynamicParameters();
            parameters.Add("?UserId", userId, DbType.Int64);
            parameters.Add("?Pending", CashOutStatusType.Pending.ToString(), DbType.AnsiString);
            return this.databaseContext.Slave.ExecuteScalar(sql, parameters).ToBoolean();
        }
    }
}